package com.kitty.game.fight.bean;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.boss.config.BossSet;
import com.kitty.game.config.Skill;
import com.kitty.game.config.XinJun;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.fight.message.vo.FightMember;
import com.kitty.game.fight.message.vo.SkillGroup;
import com.kitty.game.fight.service.CountService;
import com.kitty.game.fight.util.FightRateUtil;
import com.kitty.game.item.config.ChangeCard;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.role.model.Role;
import com.kitty.game.skill.model.RoleSkill;
import com.kitty.game.utils.Const;
import com.kitty.game.utils.FormulaUtil;
import com.kitty.game.utils.StatusConst;
import com.kitty.game.waiguan.CustomFasionIcon;
import lombok.Data;
import org.apache.mina.core.session.IoSession;
import org.nutz.lang.util.NutMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
public class FightObject implements Comparable<FightObject> {
    protected int id;
    protected String name;
    protected short level;
    protected int currLife;
    protected int maxLife;
    protected int weaponId;
    protected int suitIcon;
    protected int currMana;
    protected int maxMana;
    protected int defense;
    protected int speed;
    protected int phyPower;
    protected int magPower;
    protected boolean doAction = false;// false没出手 ,true已出手
    protected int hostId;
    protected int fightPetId;
    protected boolean monster;// 是否是怪物
    protected ArrayList<Integer> skillIds;
    protected int targetId = 0;
    protected int type;// 出手动作 2物攻 3法攻 1防御 4使用道具 8 召唤宠物
    protected int skillId;
    protected byte AutoFight = 0;
    protected NutMap statusMap = new NutMap();
    protected int pos;
    protected short polar;

    protected int icon;
    protected byte action;// 缺法力时操作 1/自动加法力 2/自动物攻
    protected boolean isASide = false;// 是否A方
    protected int autoFightType;// 自动战斗类型
    protected int autoSkillId;// 自动战斗技能ID
    protected byte multiIndex;//自动战斗类型 1是组合战斗 0是普通
    protected int autoTarget;// 自动战斗目标

    protected BossSet bossSet;// boss的数据
    protected int reviveSize = 0;//复活次数
    protected List<NutMap> fightMsg;
    protected List<SkillGroup> skillGroups;
    protected Map<String, Object> tempCache;
    private Map<Integer, Boolean> isCompleted = new HashMap<>();
    private Map<Integer, Boolean> isRequested = new HashMap<>();
    private NutMap roundController = NutMap.NEW();

    private int fulingtype ;
    private int fulingdengji ;

    private int special_icon ;
    private int specialiconIsok ;
    //阵法相性
    protected short zhenfaPolar;
    //阵法是否生效
    private int isZhenfa;
    //变身卡信息
    protected ChangeCard changeCard;

    public void setDoAction(boolean doAction) {
        this.doAction = doAction;
    }

    public void setType(int type) {
        this.type = type;
    }

    /**
     * 判断当前回合是否操作过
     * 如果返回真说明操作过了,不做处理
     * 没有出手才继续之后的代码
     */
    public boolean isCompleted(int round, boolean bo) {
        boolean boo = isCompleted.getOrDefault(round, false);
        if (!boo && bo) {
            isCompleted.put(round, true);
        }
        return boo;
    }

    /**
     * 判断当前回合是否请求过面板
     * 如果返回真说明请求过了,不做处理
     * 没有请求过面板才继续之后的代码
     * bo true 请求并更新状态 false 只判断 不更新状态
     */
    public boolean isRequested(int round, boolean bo) {
        boolean boo = isRequested.getOrDefault(round, false);
        if (!boo && bo) {
            isRequested.put(round, true);
        }
        return boo;
    }

    /**
     * 技能ID取技能
     */
    public RoleSkill getSkillBy(int skillId) {
        Skill skill = SpringUtils.getSkillService().getSkillInfo(skillId);
        if (skill == null) {
            return null;
        }
        return new RoleSkill(skill, getLevel());
    }

    public void setCurrLife(int currLife) {
        if (currLife > maxLife) {
            this.currLife = this.maxLife;
        } else {
            this.currLife = Math.max(currLife, 0);
        }
    }

    public int setCurrMana(int currMana) {
        if (currMana > maxMana) {
            this.currMana = this.maxMana;
        } else {
            this.currMana = Math.max(currMana, 0);
        }
        return this.currMana;
    }

    /**
     * 扣蓝
     * @param mp
     * @return
     */
    public int reduceMp(int mp) {
        this.currMana -= mp;
        if (this.currMana < 0) {
            this.currMana = 0;
        }
        return this.currMana;
    }

    public boolean isFallDown() {
        return this.currLife <= 0;
    }

    public NutMap getStatusMap() {
        if (statusMap == null) {
            setStatusMap(NutMap.NEW());
        }
        return statusMap;
    }

    public void setStatus(int status, int value) {
        getStatusMap().setv(String.valueOf(status), value);
    }

    public void removeStatus(int status) {
        getStatusMap().unset(String.valueOf(status));
        getStatusMap().unset(status + "value");
    }

    public void setStatusScore(int status, int value) {
        getStatusMap().setv(status + "value", value);
    }

    public int getStatusScore(int status) {
        return getStatusMap().getInt(status + "value", 0);
    }

    public int getStatusValue(int status) {
        String key = String.valueOf(status);
        return getStatusMap().getInt(key, 0);
    }

    public FightMember asFightMember(List<CustomFasionIcon> customIconList) {
        return null;
    }

    public FightMember asFightMember() {
        FightMember fightMember = new FightMember();
        fightMember.setId(getId());
        fightMember.setWeapon_icon((short) 0);
        fightMember.setPosition((short) getPos());
        fightMember.setIcon((short) getIcon());
        fightMember.setList(asFieldValues());
        fightMember.setColor((short)3);
        return fightMember;
    }

    public List<FiedValue> asFieldValues() {
        ArrayList<FiedValue> fiedValues = new ArrayList<>();
        fiedValues.add(new FiedValue(1, 4, getName()));
        fiedValues.add(new FiedValue(40, 7, getIcon()));
        fiedValues.add(new FiedValue(41, 7, (short) 2));
        fiedValues.add(new FiedValue(204, 3, 0));
        fiedValues.add(new FiedValue(341, 1, (byte) 0));
        fiedValues.add(new FiedValue(340, 1, (byte) 0));
        return fiedValues;
    }

    /**
     * 判断对象是不是守护
     */
    public boolean isGuard() {
        return this instanceof GuardFightObject;
    }

    /**
     * 判断对象是不是宠物
     */
    public boolean isPet() {
        return this instanceof PetFightObject;
    }

    /**
     * 判断对象是不是玩家
     */
    public boolean isPlayer() {
        return this instanceof PlayerFightObject;
    }

    /**
     * 判断对象是不是怪物
     */
    public boolean isMonster() {
        if (monster) {
            return true;
        }
        if (this instanceof MonsterFightObject) {
            return true;
        }
        return this instanceof BossFightObject;
    }

    /**
     * 取道行
     */
    public int getTao() {
        return (int)FormulaUtil.getStdTao(level);
    }

    /**
     * 判断对象是不是人物镜像
     */
    public boolean isRoleMirror() {
        return this instanceof RoleMirrorFightObject;
    }

    /**
     * 判断对象是不是宠物镜像
     */
    public boolean isPetMirror() {
        return this instanceof PetMirrorFightObject;
    }

    /**
     * 判断对象是不是超级boss
     */
    public boolean isSuperBoss() {
        return this instanceof SuperBossFightObject;
    }

    /**
     * 判断对象是不是超级boss阵魄
     */
    public boolean isSuperBossZP() {
        return this instanceof SuperBossZPFightObject;
    }

    /**
     * 判断对象是不是超级boss减伤阵魄
     */
    public boolean isSuperBossZPJS() {
        return this instanceof SuperBossZPJSFightObject;
    }


    public NutMap getExtraAttr() {
        return NutMap.NEW();
    }

    @Override
    public int compareTo(FightObject o) {
        //重新排序。定义出手技能
        int speed1 = o.getSpeedSum();
        int speed0 = getSpeedSum();
        o.isDefense();
        if(o.getSkillId() == 265 || o.getType() == 1 || o.getSkillId() == 475 ){
            speed1 = 10000000;
        }
        if(getSkillId() == 265  || getType() == 1 || getSkillId() == 475){
            speed0 = 10000000;
        }
        return speed1 - speed0;
    }

    private int getSpeedSum() {
        int extraSpeed = statusMap.getInt(StatusConst.STATUS_SPEED_UP + "value", 0);
        if (statusMap.getInt(String.valueOf(StatusConst.STATUS_SPEED_UP), 0) == 0) {
            extraSpeed = 0;
        }
        return getSpeed() + extraSpeed;
    }

    /**
     * 临时保存数据
     */
    public Object pushTempCache(String key, Object value) {
        if (tempCache == null) {
            tempCache = new HashMap<>(4);
        }
        return tempCache.put(key, value);
    }

    /**
     * 弹出临时保存数据
     */
    @SuppressWarnings("unchecked")
    public <T> T popTempCache(String key, Object dft) {
        if (tempCache == null) {
            return (T) dft;
        }
        if (tempCache.containsKey(key)) {
           return  (T) tempCache.remove(key);
        }
        return (T) dft;
    }

    /**
     * 弹出临时保存数据
     */
    @SuppressWarnings("unchecked")
    public <T> T getTempCache(String key, Object dft) {
        if (tempCache == null) {
            return null;
        }
        T result = (T) tempCache.get(key);
        return result == null ? (T) dft : result;
    }

    /**
     * 是否在冰冻状态
     */
    public boolean isFrozen() {
        return getStatusValue(StatusConst.STATUS_FROZEN) >= 1;
    }

    /**
     * 是否在中毒状态
     */
    public boolean isPoison() {
        return getStatusValue(StatusConst.STATUS_POISON) >= 1;
    }

    /**
     * 是否在混乱状态
     */
    public boolean isConfusion() {
        return getStatusValue(StatusConst.STATUS_CONFUSION) >= 1;
    }

    /**
     * 是否在防御状态
     */
    public boolean isDefense() {
        return getStatusValue(StatusConst.STATUS_DEFENSE) >= 1;
    }

    /**
     * 是否在昏睡状态
     */
    public boolean isSleep() {
        return getStatusValue(StatusConst.STATUS_SLEEP) >= 1;
    }

    /**
     * 是否在遗忘状态
     */
    public boolean isForgotten() {
        return getStatusValue(StatusConst.STATUS_FORGOTTEN) >= 1;
    }

    /**
     * 处于障碍状态
     *
     * @return
     */
    public boolean inDeBuffStatus() {
        return isFrozen() || isPoison() || isConfusion() || isSleep() || isForgotten();
    }

    /**
     * 取技能增益伤害 物攻法攻都是这个
     */
    public int getExtraAttack() {
        if (statusMap.getInt(String.valueOf(StatusConst.STATUS_PHY_POWER_UP), 0) >= 1) {
            return statusMap.getInt(StatusConst.STATUS_PHY_POWER_UP + "value", 0);
        }
        return 0;
    }

    /**
     * 取技能增益防御
     */
    public int getExtraDefense() {
        if (statusMap.getInt(String.valueOf(StatusConst.STATUS_DEF_UP), 0) >= 1) {
            return statusMap.getInt(StatusConst.STATUS_DEF_UP + "value", 0);
        }
        return 0;
    }

    /**
     * 取技能增益躲避
     */
    public int getExtraDodge() {
        if (statusMap.getInt(String.valueOf(StatusConst.STATUS_DODGE_UP), 0) >= 1) {
            return statusMap.getInt(StatusConst.STATUS_DODGE_UP + "value", 0);
        }
        return 0;
    }

    public Role getRole() {
        return null;
    }

    public Pet getPet() {
        return null;
    }

    public XinJun getXinjun() {
        return null;
    }

    /**
     * 根据自己的相性取目标的抗性
     */
    public int getTargetResistValue(FightObject target) {
        int targetResist = 0;
        short polar = this.getPolar();
        if (polar == Const.SCHOOL_METAL) {
            if (target.isPet()) {
                targetResist = target.getPet().getResistMetal();
            } else if (target.isPlayer()) {
                targetResist = target.getRole().getResistMetal();
            } else if (target.getXinjun() != null) {
                targetResist = Integer.parseInt(target.getXinjun().getResist_metal());
            }
        } else if (polar == Const.SCHOOL_WOOD) {
            if (target.isPet()) {
                targetResist = target.getPet().getResistWood();
            } else if (target.isPlayer()) {
                targetResist = target.getRole().getResistWood();
            } else if (target.getXinjun() != null) {
                targetResist = Integer.parseInt(target.getXinjun().getResist_wood());
            }
        } else if (polar == Const.SCHOOL_WATER) {
            if (target.isPet()) {
                targetResist = target.getPet().getResistWater();
            } else if (target.isPlayer()) {
                targetResist = target.getRole().getResistWater();
            } else if (target.getXinjun() != null) {
                targetResist = Integer.parseInt(target.getXinjun().getResist_water());
            }
        } else if (polar == Const.SCHOOL_FIRE) {
            if (target.isPet()) {
                targetResist = target.getPet().getResistFire();
            } else if (target.isPlayer()) {
                targetResist = target.getRole().getResistFire();
            } else if (target.getXinjun() != null) {
                targetResist = Integer.parseInt(target.getXinjun().getResist_fire());
            }
        } else if (polar == Const.SCHOOL_EARTH) {
            if (target.isPet()) {
                targetResist = target.getPet().getResistEarth();
            } else if (target.isPlayer()) {
                targetResist = target.getRole().getResistEarth();
            } else if (target.getXinjun() != null) {
                targetResist = Integer.parseInt(target.getXinjun().getResist_earth());
            }
        }
        return targetResist;
    }


    /**
     * 根据自己的相性判断是否是五行相克
     */
    public boolean isRestraint(FightObject target) {
        boolean isRestraint = false;
        short polar = this.getPolar();
        short targetPolar = target.getPolar();
        if (polar == Const.SCHOOL_METAL) {
            if (targetPolar == Const.SCHOOL_WOOD) {
                isRestraint = true;
            }
        } else if (polar == Const.SCHOOL_WOOD) {
            if (targetPolar == Const.SCHOOL_EARTH) {
                isRestraint = true;
            }
        } else if (polar == Const.SCHOOL_WATER) {
            if (targetPolar == Const.SCHOOL_FIRE) {
                isRestraint = true;
            }
        } else if (polar == Const.SCHOOL_FIRE) {
            if (targetPolar == Const.SCHOOL_METAL) {
                isRestraint = true;
            }
        } else if (polar == Const.SCHOOL_EARTH) {
            if (targetPolar == Const.SCHOOL_WATER) {
                isRestraint = true;
            }
        }
        return isRestraint;
    }

    /**
     * 计算星君抵抗
     */
    public Double countAbsorb(long id, Double result, String absorb) {
        Role role = SpringUtils.getRoleService().getOnlinePlayer(id);
        if (role != null) {
            if (role.getActivity().getRoleTowerData() != null) {
                int currentLayer = role.getActivity().getRoleTowerData().getCurrentLayer();
                int num = currentLayer - role.getLevel();
                if (num > 0) {
                    num = num * 2 + Integer.parseInt(absorb);
                    result = result * (1 - num / 100.00);
                }
            } else {
                result = result - Integer.parseInt(absorb);
            }
        }
        return result;
    }

    /**
     * 取出手的物理攻击伤害 默认
     */
    public int getPhyHurt(FightObject target, boolean isPenetrate) {
        int hurt = this.getPhyPower() + FightRateUtil.getRandHurt(this.getPhyPower()) - target.getDefense() - target.getExtraDefense();
        //这里修复 仙道点的减伤   //貌似还有抗物理
        hurt = CountService.getHurtByReduce(hurt,target,false);
        if (target.getId() != targetId) {
            hurt /= 2;
        }
        return hurt;
    }

    /**
     * 取出手的物理攻击伤害
     */
    public int getPhyHurt(FightObject target, boolean isPenetrate, double penetrateRate) {
        int targetDefense = target.getDefense() + target.getExtraDefense();

        if (isPenetrate) {
            targetDefense = (int)(targetDefense * penetrateRate);
        }
        int hurt = this.getPhyPower() + FightRateUtil.getRandHurt(this.getPhyPower()) - targetDefense;
        //这里修复仙道点的减伤   //貌似还有抗物理
        hurt = CountService.getHurtByReduce(hurt,target,false);
        if (target.getId() != targetId) {
            hurt /= 2;
        }
        return hurt;
    }

    /**
     * 取出手的法术攻击伤害  默认
     */
    public int getMagHurt(FightObject target, boolean isPenetrate) {
        RoleSkill skill = getSkillBy(getSkillId());
        int hurt;
        boolean isRestraint = isRestraint(target);// 五行相克
        int targetResist = getTargetResistValue(target);//抗性
        int targetDefense = target.getDefense();
        if (isPenetrate) {
        	targetDefense = (int)(targetDefense * 0.3);
        }
        hurt = (int) (getExtraAttack() + this.getMagPower() * 1.3 + skill.getSkillJieshu() * 10 * this.getLevel() * 1.6 - (targetResist * 50 + targetDefense + target.getExtraDefense()));
        //这里修复仙道点的减伤
        hurt = CountService.getHurtByReduce(hurt,target,false);

        if (isRestraint) {
            hurt = new Double(hurt * 1.2).intValue();
        }
        return hurt;
    }

    /**
     * 取出手的法术攻击伤害
     */
    public int getMagHurt(FightObject target, boolean isPenetrate, double penetrateRate) {
        RoleSkill skill = getSkillBy(getSkillId());
        int hurt;
        boolean isRestraint = isRestraint(target);// 五行相克
        int targetResist = getTargetResistValue(target);//抗性
        int targetDefense = target.getDefense() + target.getExtraDefense();
        if (isPenetrate) {
            targetDefense = (int)(targetDefense * penetrateRate);
        }
        hurt = (int) (getExtraAttack() + this.getMagPower() * 1.3 + skill.getSkillJieshu() * 10 * this.getLevel() * 1.6 - (targetResist * 50 + targetDefense));
        //这里修复仙道点的减伤
        hurt = CountService.getHurtByReduce(hurt,target,false);
        if (isRestraint) {
            hurt = new Double(hurt * 1.2).intValue();
        }
        return hurt;
    }

    /**
     * 取role的Uid
     */
    public long getHostUid() {
        return 0;
    }

    /**
     * 清除所有辅助状态
     *
     * @return
     */
    public void clearAssistBuff() {
        removeStatus(StatusConst.STATUS_SPEED_UP);
        removeStatus(StatusConst.STATUS_PHY_POWER_UP);
        removeStatus(StatusConst.STATUS_DODGE_UP);
        removeStatus(StatusConst.STATUS_DEF_UP);
        removeStatus(StatusConst.STATUS_RECOVER_LIFE);
        removeStatus(StatusConst.STATUS_PASSIVE_ATTACK);
        removeStatus(StatusConst.STATUS_IMMUNE_PHY_DAMAGE);
        removeStatus(StatusConst.STATUS_DEADLY_KISS);
        removeStatus(StatusConst.STATUS_IMMUNE_MAG_DAMAGE);
    }

    /**
     * 清除乾坤罩
     */
    public void clearAssistBuff_STATUS_PASSIVE_ATTACK() {
        removeStatus(StatusConst.STATUS_PASSIVE_ATTACK);
    }

    /**
     * 是否拥有任意辅助状态
     *
     * @return
     */
    public boolean hasAssistBuff() {
        return getStatusValue(StatusConst.STATUS_SPEED_UP) > 0
                || getStatusValue(StatusConst.STATUS_PHY_POWER_UP) > 0
                || getStatusValue(StatusConst.STATUS_DODGE_UP) > 0
                || getStatusValue(StatusConst.STATUS_DEF_UP) > 0
                || getStatusValue(StatusConst.STATUS_RECOVER_LIFE) > 0
                || getStatusValue(StatusConst.STATUS_PASSIVE_ATTACK) > 0
                || getStatusValue(StatusConst.STATUS_IMMUNE_PHY_DAMAGE) > 0
                || getStatusValue(StatusConst.STATUS_DEADLY_KISS) > 0
                || getStatusValue(StatusConst.STATUS_IMMUNE_MAG_DAMAGE) > 0;
    }

    /**
     * 清除所有障碍状态
     *
     * @return
     */
    public void clearObstacleBuff() {
        removeStatus(StatusConst.STATUS_POISON);
        removeStatus(StatusConst.STATUS_SLEEP);
        removeStatus(StatusConst.STATUS_FORGOTTEN);
        removeStatus(StatusConst.STATUS_FROZEN);
        removeStatus(StatusConst.STATUS_CONFUSION);
    }


    /**
     * 取战斗对象的session 如果是宠物就拿人物的
     */
    public IoSession getSession() {
       return null;
    }


    @Override
    public String toString() {
        return "FightObject{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

}
